/********************************************************************************/
/*   The  Software  is  proprietary,  confidential,  and  valuable to Realtek   */
/*   Semiconductor  Corporation  ("Realtek").  All  rights, including but not   */
/*   limited  to  copyrights,  patents,  trademarks, trade secrets, mask work   */
/*   rights, and other similar rights and interests, are reserved to Realtek.   */
/*   Without  prior  written  consent  from  Realtek,  copying, reproduction,   */
/*   modification,  distribution,  or  otherwise  is strictly prohibited. The   */
/*   Software  shall  be  kept  strictly  in  confidence,  and  shall  not be   */
/*   disclosed to or otherwise accessed by any third party.                     */
/*   c<2003> - <2012>                                                           */
/*   The Software is provided "AS IS" without any warranty of any kind,         */
/*   express, implied, statutory or otherwise.                                  */
/********************************************************************************/

//----------------------------------------------------------------------------------------------------
// ID Code      : RTD2014Key.c No.0000
// Update Note  :
//----------------------------------------------------------------------------------------------------

#define __KEC_KEY__

#include "UserCommonInclude.h"

#if(_OSD_TYPE == _KEC_OSD)

//****************************************************************************
// DEFINITIONS / MACROS
//****************************************************************************
//--------------------------------------------------
// Definitions of Key Mask
//--------------------------------------------------
#define _RELEASE_KEY_MASK                           0x00
#define _POWER_KEY_MASK                             0x01
#define _MENU_KEY_MASK                              0x02
#define _RIGHT_KEY_MASK                             0x03//0x04
#define _LEFT_KEY_MASK                              0x04//0x08
#define _EXIT_KEY_MASK                              0x05//0x10
#define _AUTO_KEY_MASK                              0x06//0x20
#define _KEY6_MASK                                  0x07//0x40
#define _KEY7_MASK                                  0x08//0x80
#define _UP_KEY_MASK                                0x09
#define _DOWN_KEY_MASK                              0x0A
#define _SOURCE_KEY_MASK                            0x0B
#define _MUTE_KEY_MASK                              0x0C
#define _VOL_INC_KEY_MASK                           0x0D
#define _VOL_DEC_KEY_MASK                           0x0E
#define _BRIGHTNESS_INC_KEY_MASK                   	0x0F
#define _BRIGHTNESS_DEC_KEY_MASK                 	0x10
#define _CONTRAST_INC_KEY_MASK                 		0x11
#define _CONTRAST_DEC_KEY_MASK                  	0x12
#define _BACKLIGHT_INC_KEY_MASK                   	0x13
#define _BACKLIGHT_DEC_KEY_MASK                 	0x14
#define _LIGHTBOX_KEY_MASK                 			0x15


//#define _POWER_RIGHT_KEY_MASK                       (_POWER_KEY_MASK | _RIGHT_KEY_MASK)
//#define _POWER_MENU_KEY_MASK                        (_POWER_KEY_MASK | _MENU_KEY_MASK)
//#define _POWER_LEFT_RIGHT_KEY_MASK                  (_POWER_KEY_MASK | _LEFT_KEY_MASK | _RIGHT_KEY_MASK)
#define _REPEAT_IR_CNT                          	5

//--------------------------------------------------
// Definitions of IR Key Code
//--------------------------------------------------
#if(_IR_SUPPORT == _IR_HW_SUPPORT)
#define _IR_DRAGON_DEMO			0
#define _IR_MIDE				1
#define _IR_JZR					2
#define _IR_GuanBai				3

#define IR_CONTROLLER			_IR_GuanBai//_IR_JZR

#if(IR_CONTROLLER == _IR_DRAGON_DEMO)
#define _IR_CUSTOMER_CODE			0xBF00
#elif(IR_CONTROLLER == _IR_MIDE)
#define _IR_CUSTOMER_CODE			0xBF00
#elif(IR_CONTROLLER == _IR_JZR)
#define _IR_CUSTOMER_CODE			0xDF20
#elif(IR_CONTROLLER == _IR_GuanBai)
#define _IR_CUSTOMER_CODE			0x6B86
#endif

DWORD code ucIRkeyMap[][2] = 
{
	#if(IR_CONTROLLER == _IR_DRAGON_DEMO)
	{0xFF00,_POWER_KEY_MASK},
	{0xEF10,_MENU_KEY_MASK},
	{0xEE11,_RIGHT_KEY_MASK},
	{0xED12,_LEFT_KEY_MASK},
	{0xEA15,_EXIT_KEY_MASK},
	#elif(IR_CONTROLLER == _IR_MIDE)
	{0xFF00,_POWER_KEY_MASK},
	{0xEF10,_MENU_KEY_MASK},	
	{0xE916,_MENU_KEY_MASK},
	{0xED12,_RIGHT_KEY_MASK},
	{0xEE11,_LEFT_KEY_MASK},
	{0xEA15,_EXIT_KEY_MASK},
	#elif(IR_CONTROLLER == _IR_JZR)
    {0xBE41,_POWER_KEY_MASK},
    {0xAF50,_MUTE_KEY_MASK},
    
	//{0xBC43,_SOURCE_DEC_KEY_MASK},
    //{0xBD42,_SOURCE_INC_KEY_MASK},
    {0xE41B,_MENU_KEY_MASK},    
    {0xB04F,_RIGHT_KEY_MASK},
    {0xE51A,_LEFT_KEY_MASK},
    
    {0xBD42,_UP_KEY_MASK},
    {0xBC43,_DOWN_KEY_MASK},
    //{0xEB14,_BRI_DEC_KEY_MASK},
    //{0xB24D,_BRI_INC_KEY_MASK},
    
    {0xA55A,_SOURCE_KEY_MASK},
    
    //{0xA956,_DISP_INFO_MASK},
    {0xAE51,_EXIT_KEY_MASK},

	#elif(IR_CONTROLLER == _IR_GuanBai)
    {0xED12,_POWER_KEY_MASK},
    {0xE11E,_SOURCE_KEY_MASK},//_EXIT_KEY_MASK},

    {0xE51A,_UP_KEY_MASK},    
    {0xFD02,_MENU_KEY_MASK},    
    {0xFC03,_RIGHT_KEY_MASK},
    {0xFE01,_LEFT_KEY_MASK},
    {0xFA05,_DOWN_KEY_MASK},    

    {0xFB04,_MUTE_KEY_MASK},    
    {0xF906,_AUTO_KEY_MASK},  
    
    {0xF807,_VOL_INC_KEY_MASK},    
    {0xF50A,_VOL_DEC_KEY_MASK}, 
    
    {0xF708,_BACKLIGHT_INC_KEY_MASK},    
    {0xE41B,_BACKLIGHT_DEC_KEY_MASK}, 
    
    {0xF609,_CONTRAST_INC_KEY_MASK},    
    {0xE01F,_CONTRAST_DEC_KEY_MASK},    


	#endif
};

#if(0)
#if(IR_CONTROLLER == _IR_DRAGON_DEMO)
#define _IR_CUSTOMER_CODE			0xBF00
#define _IR_CODE_KEY_POWER                        0xFF00  
#define _IR_CODE_KEY_MENU                          0xEF10 
#define _IR_CODE_KEY_RIGHT                         0xEE11 
#define _IR_CODE_KEY_LEFT                           0xED12
#define _IR_CODE_KEY_EXIT                           0xEA15

#else
#warning "Not selsect IR controller,  _IR_SUPPORT should be Off "
#endif

/*
#if(_IR_PROTOCAL == _IR_NEC_DTV328)
#define _IR_CODE_KEY_POWER                          0xA0FB
#define _IR_CODE_KEY_MENU                           0xAAFB
#define _IR_CODE_KEY_RIGHT                          0xEBFB
#define _IR_CODE_KEY_LEFT                           0xA9FB
#define _IR_CODE_KEY_EXIT                           0xEFFB

#elif(_IR_PROTOCAL == _IR_SONY_B102P)
#define _IR_CODE_KEY_POWER                          0x0950
#define _IR_CODE_KEY_MENU                           0x0A50
#define _IR_CODE_KEY_RIGHT                          0x0920
#define _IR_CODE_KEY_LEFT                           0x0930
#define _IR_CODE_KEY_EXIT                           0x0940

#elif(_IR_PROTOCAL == _IR_PHILIPS_RC6)
#define _IR_CODE_KEY_POWER                          0x000C
#define _IR_CODE_KEY_MENU                           0x005C
#define _IR_CODE_KEY_RIGHT                          0x005B
#define _IR_CODE_KEY_LEFT                           0x005A
#define _IR_CODE_KEY_EXIT                           0x000A

#endif

*/
#endif
#endif


//****************************************************************************
// STRUCT / TYPE / ENUM DEFINITTIONS
//****************************************************************************


//****************************************************************************
// CODE TABLES
//****************************************************************************


//****************************************************************************
// VARIABLE DECLARATIONS
//****************************************************************************
BYTE g_ucKeyStatePrev;
BYTE g_ucKeyStateCurr;
BYTE g_ucKeyStateSkip;

#if(_AD_KEY_SUPPORT == _ON)
BYTE g_ucBackupKeyState = 0xFF;
#endif

BYTE g_IRKeyRepeatTimes = 0;
BYTE g_IRKeyValue;
BYTE g_queue[5] = {0,0,0,0,0};

//****************************************************************************
// FUNCTION DECLARATIONS
//****************************************************************************
void UserInterfaceKeyHandler(void);
void RTDKeyInitial(void);
bit RTDKeyScanReady(void);
BYTE RTDKeyScan(void);
bit RTDKeyPowerKeyProc(void);
void RTDKeyPowerKeyMix(void);
void RTDKeyMessageProc(void);
void RTDKeyMessageConvert(BYTE ucKeyMask, BYTE ucKeyMsg);

bit RTDKeySpecialProc(BYTE ucKeyMask);
void RTDKeyHoldKeyTimerCancel(void);
void RTDKeyHoldKeyCheck(void);


#if(_IR_SUPPORT == _IR_HW_SUPPORT)
BYTE RTDIRKeyScan(void);
#endif

//****************************************************************************
// FUNCTION DEFINITIONS
//****************************************************************************
//--------------------------------------------------
// Description  : Key Handler, executed in the main loop.
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void UserInterfaceKeyHandler(void)
{
    // Skip key status update for tool
    if(g_ucKeyStateSkip != 0)
    {
        g_ucKeyStateSkip = 0;
        return;
    }

    // Clear the key message
    if(GET_KEYMESSAGE() != _HOLD_KEY_MESSAGE)
    {
        SET_KEYMESSAGE(_NONE_KEY_MESSAGE);
    }

    if(RTDKeyScanReady() == _TRUE)
    {
        // Store previous key state
        g_ucKeyStatePrev = g_ucKeyStateCurr;

        // Get current key state
        g_ucKeyStateCurr = RTDKeyScan();
        
		#if(_IR_SUPPORT == _IR_HW_SUPPORT)
        if(g_ucKeyStateCurr == 0x00)
        {
            // DebugMessageUser("_IR_HW_SUPPORT", 1);
            g_ucKeyStateCurr = RTDIRKeyScan();
            if(g_ucKeyStateCurr != 0)
            DebugMessageIR("g_ucKeyStateCurr",g_ucKeyStateCurr);

            if((g_ucKeyStateCurr == _RELEASE_KEY_MASK) && (g_IRKeyRepeatTimes > 0))
            {
                --g_IRKeyRepeatTimes;
                if(g_IRKeyRepeatTimes != 0)
                {
                    g_ucKeyStateCurr = g_IRKeyValue;
                    DebugMessageIR("-VIN-Repeat",g_IRKeyRepeatTimes);
                }
            }
           
        }
        else
        {
            g_IRKeyRepeatTimes = 0;
            g_IRKeyValue = _RELEASE_KEY_MASK;
        }
        
		#endif // End of #if(_IR_SUPPORT == _IR_HW_SUPPORT)

        // Power key process, return if power key is pressed
        if(RTDKeyPowerKeyProc() == _TRUE)
        {
            return;
        }

        // Convert key state to key message, store in (ucKeyNotify)
        RTDKeyMessageProc();
    }
}

//--------------------------------------------------
// Description  : Key intial.
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void RTDKeyInitial(void)
{
    CLR_KEYSCANREADY();
    CLR_KEYSCANSTART();
}

//--------------------------------------------------
// Description  : Key scan ready process. We wait 0.02 sec in order to keep the keypad debounce
// Input Value  : None
// Output Value : None
//--------------------------------------------------
bit RTDKeyScanReady(void)
{
    if((GET_KEYSCANSTART() == _TRUE) &&
       (GET_KEYSCANREADY() == _TRUE))
    {
        return _TRUE;
    }
    else if(GET_KEYSCANSTART() == _FALSE)
    {
        // Set Scan start flag.
        SET_KEYSCANSTART();

        // SET_KEYSCANREADY();
        // Wait 0.02 sec in order to keep the keypad debounce
        ScalerTimerReactiveTimerEvent(SEC(0.01), _USER_TIMER_EVENT_KEY_SCAN_READY);

        return _FALSE;
    }

    return _FALSE;
}

//--------------------------------------------------
// Description  : Get key status
// Input Value  : None
// Output Value : Return Key status
//--------------------------------------------------
BYTE RTDKeyScan(void)
{
    BYTE ucKeyState = 0;
    BYTE ucVoltage0 = 0;
    BYTE ucVoltage1 = 0;
    BYTE ucVoltage2 = 0;
    BYTE ucVoltage3 = 0;
	//static WORD ucPowerCount = 0;
	
#if(_AD_KEY_SUPPORT == _ON)
    ucVoltage0 = PCB_ADKEY0();
    ucVoltage1 = PCB_ADKEY1();
    ucVoltage2 = PCB_ADKEY2();
    ucVoltage3 = PCB_ADKEY3();

    PCB_KEY_STATE(ucVoltage0, ucVoltage1, ucVoltage2, ucVoltage3, ucKeyState);

	/*#if(_IR_SUPPORT == _IR_HW_SUPPORT)
        if(ucKeyState == 0x00)
        {
            ucKeyState = RTDIRKeyScan();
            if((ucKeyState != 0x00) && (g_ucBackupKeyState == 0xff))
            {
                g_ucBackupKeyState = ucKeyState;
				return ucKeyState;
            }
        }
	#endif // End of #if(_IR_SUPPORT == _IR_HW_SUPPORT)*/

	#if(_KEYBOARD_TYPE == _KB_QN_TYPEC)
	if(ucKeyState == _EXIT_KEY_MASK)
	{
        if(SysPowerGetPowerStatus() == _POWER_STATUS_OFF)
        {
			ucKeyState = _POWER_KEY_MASK;
        }
        /*else
        {
			if(GET_OSD_STATE() == _MENU_NONE)
			{
				ucKeyState = _SOURCE_KEY_MASK;
			}
        }*/

	}
	#endif
	/*ucPowerCount++;
	if(ucPowerCount >= 300)
	{
		ucPowerCount = 0;
        DebugMessageSystem("Power Status", SysPowerGetPowerStatus());
        DebugMessageSystem("Mode Status", SysModeGetModeState());
	}*/
	if(ucVoltage1<248)
	{
        //DebugMessageSystem("key 1", ucVoltage1);

	}
	//return ucKeyState;
	if(ucVoltage2<248)
	{
        //DebugMessageSystem("key 2", ucVoltage2);

	}
	//Right:C8
	//Menu:88
	//
    if(g_ucBackupKeyState == ucKeyState)
    {
        if(GET_KEYREPEATENABLE() != _ON)
        {
            RTDKeyInitial();
        }

        return g_ucBackupKeyState;
    }
    else
    {
        g_ucBackupKeyState = ucKeyState;
        ucKeyState = 0;
    }

#else
    PCB_KEY_STATE(ucVoltage0, ucVoltage1, ucVoltage2, ucVoltage3, ucKeyState);
#endif // End of #if(_AD_KEY_SUPPORT == _ON)


    if(ucKeyState != 0)
    {
        RTDKeyInitial();
    }

    return ucKeyState;
}

//--------------------------------------------------
// Description  : Power key process
// Input Value  : None
// Output Value : Return _TRUE if power key is pressed
//--------------------------------------------------
bit RTDKeyPowerKeyProc(void)
{
    if(g_ucKeyStateCurr == _POWER_KEY_MASK)//((g_ucKeyStateCurr & _POWER_KEY_MASK) != 0)
    {
    	DebugMessageIR("g_ucKeyStateCurr", g_ucKeyStateCurr);
    	DebugMessageIR("g_ucKeyStatePrev", g_ucKeyStatePrev);
        if(g_ucKeyStatePrev != _POWER_KEY_MASK)//((g_ucKeyStatePrev ^ g_ucKeyStateCurr) == _POWER_KEY_MASK)//(((g_ucKeyStatePrev ^ g_ucKeyStateCurr) & _POWER_KEY_MASK) != 0)
        {
            RTDKeyPowerKeyMix();
            DebugMessageIR("SysPowerGetPowerStatus()", SysPowerGetPowerStatus());

            if((SysPowerGetPowerStatus() == _POWER_STATUS_OFF) || (SysPowerGetPowerStatus() == _POWER_STATUS_FAKE_OFF))
            {
                DebugMessageIR("Power On", g_ucKeyStateCurr);
                SET_OSD_STATE(_MENU_NONE);
                SET_OSD_IN_FACTORY_MENU_STATUS(_FALSE);
                
                if(GET_OSD_FACTORY_MODE_BRUNIN())
                {
                    SET_OSD_FACTORY_MODE_BRUNIN(_OFF);
                    RTDNVRamSaveOSDData();
                }    
                SysPowerSetTargetPowerStatus(_POWER_STATUS_NORMAL);
            }
            else
            {
                DebugMessageIR("Power Off", g_ucKeyStateCurr);
                SysPowerSetTargetPowerStatus(_POWER_STATUS_OFF);
            }

            return _TRUE;
        }
    }

    return _FALSE;
}

//--------------------------------------------------
// Description  : We can add some settings here while combo key with power key
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void RTDKeyPowerKeyMix(void)
{/*
    switch(g_ucKeyStateCurr)
    {
        case _POWER_RIGHT_KEY_MASK:
            break;

        case _POWER_MENU_KEY_MASK:
            break;

        case _POWER_LEFT_RIGHT_KEY_MASK:
            break;

        default:
            break;
    }*/
}


//--------------------------------------------------
// Description  : Convert keypad status into key message, stores in ucKeyNotify
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void RTDKeyMessageProc(void)
{
    switch(g_ucKeyStateCurr)
    {
        case _MENU_KEY_MASK:
            CLR_KEYREPEATENABLE();
            RTDKeyMessageConvert(_MENU_KEY_MASK, _MENU_KEY_MESSAGE);
            DebugMessageSystem("menu proc", GET_KEYMESSAGE());
            break;

        case _RIGHT_KEY_MASK:
       	 	#if(_KEYBOARD_TYPE == _KB_QN_NORMAL)  
            	if(GET_OSD_STATE() == _MENU_NONE)
            	{
                    RTDKeyMessageConvert(_RIGHT_KEY_MASK, _VOL_DEC_KEY_MESSAGE);
                }
                else
                {
                    RTDKeyMessageConvert(_RIGHT_KEY_MASK, _RIGHT_KEY_MESSAGE);
                }
       	 	#else
            RTDKeyMessageConvert(_RIGHT_KEY_MASK, _RIGHT_KEY_MESSAGE);
            #endif
            break;

        case _LEFT_KEY_MASK:
            RTDKeyMessageConvert(_LEFT_KEY_MASK, _LEFT_KEY_MESSAGE);
            break;

		case _UP_KEY_MASK:
            RTDKeyMessageConvert(_UP_KEY_MASK, _UP_KEY_MESSAGE);
			break;
			
        case _DOWN_KEY_MASK:
            RTDKeyMessageConvert(_DOWN_KEY_MASK, _DOWN_KEY_MESSAGE);
            break;
            
		case _VOL_INC_KEY_MASK:
			RTDKeyMessageConvert(_VOL_INC_KEY_MASK, _VOL_INC_KEY_MESSAGE);
			break;
			
		case _VOL_DEC_KEY_MASK:
			RTDKeyMessageConvert(_VOL_DEC_KEY_MASK, _VOL_DEC_KEY_MESSAGE);
			break;
			
		case _BRIGHTNESS_INC_KEY_MASK:
			RTDKeyMessageConvert(_BRIGHTNESS_INC_KEY_MASK, _BRIGHTNESS_INC_KEY_MESSAGE);
			break;
			
		case _BRIGHTNESS_DEC_KEY_MASK:
			RTDKeyMessageConvert(_BRIGHTNESS_DEC_KEY_MASK, _BRIGHTNESS_DEC_KEY_MESSAGE);
			break;
		
        case _BACKLIGHT_INC_KEY_MASK:
            RTDKeyMessageConvert(_BACKLIGHT_INC_KEY_MASK, _BACKLIGHT_INC_KEY_MESSAGE);
            break;
            
        case _BACKLIGHT_DEC_KEY_MASK:
            RTDKeyMessageConvert(_BACKLIGHT_DEC_KEY_MASK, _BACKLIGHT_DEC_KEY_MESSAGE);
            break;
            
		case _CONTRAST_INC_KEY_MASK:
			RTDKeyMessageConvert(_CONTRAST_INC_KEY_MASK, _CONTRAST_INC_KEY_MESSAGE);
			break;
			
		case _CONTRAST_DEC_KEY_MASK:
			RTDKeyMessageConvert(_CONTRAST_DEC_KEY_MASK, _CONTRAST_DEC_KEY_MESSAGE);
			break;
			
        case _MUTE_KEY_MASK:
            RTDKeyMessageConvert(_MUTE_KEY_MASK, _MUTE_KEY_MESSAGE);
            break;

        case _SOURCE_KEY_MASK:
			#if (_PRODUCT_ID_SEL == PRODUCT_ID_DEMO_CDB01_D_LVDS_G286HAN01)
            if((GET_OSD_STATE() >= _MAINMENU_START) && (GET_OSD_STATE() <= _MAINMENU_END))
                RTDKeyMessageConvert(_SOURCE_KEY_MASK, _EXIT_KEY_MESSAGE);
            else
			#endif
	            RTDKeyMessageConvert(_SOURCE_KEY_MASK, _SOURCE_KEY_MESSAGE);
            break;
            
        case _EXIT_KEY_MASK:
            CLR_KEYREPEATENABLE();
			#if ((_KEYBOARD_TYPE == _KB_ZHEN_DONG_TY1519) || (_KEYBOARD_TYPE == _KB_ZHEN_DONG_2K) || (_KEYBOARD_TYPE == _KB_ZHEN_DONG_V10))

	            if(GET_OSD_STATE() == _MENU_NONE)
		            RTDKeyMessageConvert(_EXIT_KEY_MASK, _SOURCE_KEY_MESSAGE);
	            else
	                RTDKeyMessageConvert(_EXIT_KEY_MASK, _EXIT_KEY_MESSAGE);
	                
            #elif(_KEYBOARD_TYPE == _KB_QN_TYPEC)
            
	            if(GET_OSD_STATE() == _MENU_NONE)
		            RTDKeyMessageConvert(_EXIT_KEY_MASK, _SOURCE_KEY_MESSAGE);
	            else
	                RTDKeyMessageConvert(_EXIT_KEY_MASK, _EXIT_KEY_MESSAGE);
                DebugMessageSystem("key msg", GET_KEYMESSAGE());

            	//DebugMessageSystem("key msg =", GET_KEYMESSAGE());
            	
			#elif(_KEYBOARD_TYPE == _KB_QN_NORMAL)
                if(GET_OSD_STATE() == _MENU_NONE)
                    RTDKeyMessageConvert(_EXIT_KEY_MASK, _SOURCE_KEY_MESSAGE);
                else
                    RTDKeyMessageConvert(_EXIT_KEY_MASK, _EXIT_KEY_MESSAGE);
                DebugMessageSystem("key msg", GET_KEYMESSAGE());
			#else
            	RTDKeyMessageConvert(_EXIT_KEY_MASK, _EXIT_KEY_MESSAGE);
            #endif
            break;

#if 1//(_KEYBOARD_TYPE == _KB_TOPTECH)
        case _AUTO_KEY_MASK:
            CLR_KEYREPEATENABLE();
            RTDKeyMessageConvert(_AUTO_KEY_MASK, _AUTO_KEY_MESSAGE);
            break;
#endif

        default:
            if((g_ucKeyStateCurr == _RELEASE_KEY_MASK) &&
               (g_ucKeyStatePrev != _RELEASE_KEY_MASK))
            {
                RTDKeyHoldKeyCheck(); // Check key release
            }

            CLR_KEYREPEATSTART();
            CLR_KEYREPEATENABLE();
            ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_KEY_REPEAT_ENABLE);
            break;
    }
}

//--------------------------------------------------
// Description  : Key message translation
// Input Value  : ucKeyMask     --> Key mask
//                ucKeyMsg      --> Key message
// Output Value : None
//--------------------------------------------------
void RTDKeyMessageConvert(BYTE ucKeyMask, BYTE ucKeyMsg)
{
    // Key different
    if((g_ucKeyStatePrev != g_ucKeyStateCurr) && (ucKeyMask == g_ucKeyStateCurr))
    {
        // KeyLock function
        if (RTDKeySpecialProc(ucKeyMask) == _FALSE)
        {
            SET_KEYMESSAGE(ucKeyMsg);
            DebugMessageSystem("key cover", GET_KEYMESSAGE());
            RTDKeyHoldKeyTimerCancel();
        }
    }
    else // Key the same
    {
        if(GET_KEYREPEATENABLE() == _TRUE)
        {
            DebugMessageSystem("GET_KEYREPEATSTART",GET_KEYREPEATSTART());
            if(GET_KEYREPEATSTART() == _TRUE)
            {
                SET_KEYMESSAGE(ucKeyMsg);
            }
            else
            {
                // Set repeat key after 500ms.
                if(g_IRKeyValue != _RELEASE_KEY_MASK)
                	ScalerTimerActiveTimerEvent(SEC(0.01), _USER_TIMER_EVENT_KEY_REPEAT_ENABLE);
				else
	                ScalerTimerActiveTimerEvent(SEC(0.5), _USER_TIMER_EVENT_KEY_REPEAT_ENABLE);
            }
        }
    }
}


//--------------------------------------------------
// Description  :  for special key check
// Input Value  : scan Key data
// Output Value : None
//--------------------------------------------------
bit RTDKeySpecialProc(BYTE ucKeyMask)
{
    if((SysModeGetModeState() != _MODE_STATUS_POWER_OFF)&&(SysModeGetModeState() != _MODE_STATUS_POWER_SAVING))
	{
		
		#if(_PRODUCT_ID_SEL == PRODUCT_ID_QI_NI_CDB01_J_EDP_1H_1TYPEC)
	    if((ucKeyMask == _EXIT_KEY_MASK))
	    {
	        ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_POWER_KEY);
	        SET_KEY_HOLD();
	        CLR_KEYREPEATENABLE();
	        return _TRUE;
	    }
	    #endif
	    
	    if((GET_OSD_STATE() == _MAIN_OSD) && (ucKeyMask == _LEFT_KEY_MASK))
	    {
	        ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_OSD_SHOW_FACTORY_MODE);
	        SET_KEY_HOLD();
	        CLR_KEYREPEATENABLE();
	        return _TRUE;
	    }
	    
	    if((GET_OSD_STATE() == _MENU_NONE) && (ucKeyMask == _RIGHT_KEY_MASK))
	    {
	        ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_OSD_LIGHTBOX_MODE);
	        SET_KEY_HOLD();
	        CLR_KEYREPEATENABLE();
	        return _TRUE;
	    }

	    if(SysModeGetModeState() == _MODE_STATUS_ACTIVE)
	    {
		    if((GET_OSD_STATE() == _MENU_NONE) && (ucKeyMask == _EXIT_KEY_MASK))
		    {
		    	#if(_FREEZE_SUPPORT)
		        ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_OSD_SHOW_FREEZE_MODE);
		        SET_KEY_HOLD();
		        CLR_KEYREPEATENABLE();
		        return _TRUE;
		        #endif
		    }
	    }
	}  
    return _FALSE;
    
    if((GET_OSD_STATE() == _MENU_NONE) && (ucKeyMask == _LEFT_KEY_MASK))
    {
#if(_DP_SUPPORT == _ON)
        ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_OSD_SHOW_DP_VERSION_SELECT);
        SET_KEY_HOLD();
        CLR_KEYREPEATENABLE();
        return _TRUE;
#endif
    }

#if(_VGA_SUPPORT == _ON)
    // Press Exit key for 3 sec to do Auto color
    else if((GET_OSD_STATE() == _MENU_NONE) && (SysSourceGetSourceType() == _SOURCE_VGA))
    {
        if (ucKeyMask == _EXIT_KEY_MASK)
        {
            ScalerTimerActiveTimerEvent(SEC(3), _USER_TIMER_EVENT_DO_AUTO_COLOR);
            SET_KEY_HOLD();
            CLR_KEYREPEATENABLE();
            return _TRUE;
        }
    }
#endif

    return _FALSE;
}

//--------------------------------------------------
// Description  :
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void RTDKeyHoldKeyTimerCancel(void)
{
    if(GET_KEY_HOLD() == _TRUE)
    {
        CLR_KEY_HOLD();

        // list all off hold key timer event here!!!
        ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_DO_AUTO_COLOR);
#if(_DP_SUPPORT == _ON)
        ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_OSD_SHOW_DP_VERSION_SELECT);
#endif
    	ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_OSD_SHOW_FACTORY_MODE);
	    ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_OSD_SHOW_FREEZE_MODE);
		ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_OSD_LIGHTBOX_MODE);
		ScalerTimerCancelTimerEvent(_USER_TIMER_EVENT_POWER_KEY);
    }
}

//--------------------------------------------------
// Description  : Hold Key check
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void RTDKeyHoldKeyCheck(void)
{
    if(GET_KEY_HOLD() == _TRUE)
    {
        switch(g_ucKeyStatePrev)
        {
            case _EXIT_KEY_MASK:
				#if ((_KEYBOARD_TYPE == _KB_ZHEN_DONG_TY1519) || (_KEYBOARD_TYPE == _KB_ZHEN_DONG_2K) || (_KEYBOARD_TYPE == _KB_ZHEN_DONG_V10))
	                if(GET_OSD_STATE() == _MENU_NONE)
		                SET_KEYMESSAGE(_SOURCE_KEY_MESSAGE);
	                else
                        SET_KEYMESSAGE(_EXIT_KEY_MESSAGE);
                #elif(_KEYBOARD_TYPE == _KB_QN_TYPEC)     
		            if(GET_OSD_STATE() == _MENU_NONE)
		            {
		                SET_KEYMESSAGE(_SOURCE_KEY_MESSAGE);
	                }
		            else
		            {
		                SET_KEYMESSAGE(_EXIT_KEY_MESSAGE);
					}
                    DebugMessageSystem("hold key msg =", GET_KEYMESSAGE());
				#elif(_KEYBOARD_TYPE == _KB_QN_NORMAL)     
                        if(GET_OSD_STATE() == _MENU_NONE)
                        {
                            SET_KEYMESSAGE(_SOURCE_KEY_MESSAGE);
                        }
                        else
                        {
                            SET_KEYMESSAGE(_EXIT_KEY_MESSAGE);
                        }
                        DebugMessageSystem("hold key msg =", GET_KEYMESSAGE());
				#else
                    SET_KEYMESSAGE(_EXIT_KEY_MESSAGE);
				#endif
                break;

            case _MENU_KEY_MASK:
                SET_KEYMESSAGE(_MENU_KEY_MESSAGE);
                DebugMessageSystem("menu key", 1);
                break;
                
            case _RIGHT_KEY_MASK:
				#if(_KEYBOARD_TYPE == _KB_QN_NORMAL) 
	                if(GET_OSD_STATE() == _MENU_NONE)
	                {
	                    SET_KEYMESSAGE(_VOL_DEC_KEY_MESSAGE);
	                }
	                else
	                {
	                    SET_KEYMESSAGE(_RIGHT_KEY_MESSAGE);
	                }
	                
                    DebugMessageSystem("up key", GET_KEYMESSAGE());
				#else
                SET_KEYMESSAGE(_RIGHT_KEY_MESSAGE);
                #endif
                break;
                
            case _LEFT_KEY_MASK:
                SET_KEYMESSAGE(_LEFT_KEY_MESSAGE);
                break;
                
            default:
                break;
        }
        RTDKeyHoldKeyTimerCancel();
    }
}


#if(_IR_SUPPORT == _IR_HW_SUPPORT)
//--------------------------------------------------
// Description  : IR Key Scan
// Input Value  : None
// Output Value : Key Mask
//--------------------------------------------------
BYTE RTDIRKeyScan(void)
{
    BYTE pucIRCodeBuffer[8] = {0};
    WORD usKeyCode = 0;
    BYTE ucKeyState = 0;
    BYTE i;

    if(ScalerIRHWModeGetData(pucIRCodeBuffer) == _TRUE)
    {
#if(_IR_PROTOCAL == _IR_NEC_DTV328)
		usKeyCode =  (((WORD)pucIRCodeBuffer[2]) << 8) + pucIRCodeBuffer[3];
		if((pucIRCodeBuffer[0] == ~(pucIRCodeBuffer[1])) && (usKeyCode == _IR_CUSTOMER_CODE))
		{
			usKeyCode = (((WORD)pucIRCodeBuffer[0]) << 8) + pucIRCodeBuffer[1];
		}
		else
			return ucKeyState;
#elif(_IR_PROTOCAL == _IR_SONY_B102P)
        usKeyCode = (((WORD)pucIRCodeBuffer[0]) << 8) + pucIRCodeBuffer[1];

#elif(_IR_PROTOCAL == _IR_PHILIPS_RC6)
        usKeyCode = (((WORD)pucIRCodeBuffer[2]) << 8) + pucIRCodeBuffer[3];

#endif // End of #if(_IR_PROTOCAL == _IR_NEC_DTV328)

		if(usKeyCode != 0x00)
		{
			for(i = 0; i < (sizeof(ucIRkeyMap)/2); i++)
			{
			    if(usKeyCode == ucIRkeyMap[i][0])
			    {
			        ucKeyState = ucIRkeyMap[i][1];
			        break;
			    }   
			}
			usKeyCode = 0x00;
		}


    }
	if(ucKeyState != _RELEASE_KEY_MASK)
	{
		g_queue[0] = g_queue[1];
		g_queue[1] = g_queue[2];
		g_queue[2] = g_queue[3];
		g_queue[3] = g_queue[4];
		g_queue[4] = ucKeyState;
		
		DebugMessageIR("g_queue[0]",g_queue[0]);
		DebugMessageIR("g_queue[1]",g_queue[1]);
		DebugMessageIR("g_queue[2]",g_queue[2]);
		DebugMessageIR("g_queue[3]",g_queue[3]);
		DebugMessageIR("g_queue[4]",g_queue[4]);
		
		if((g_queue[0]+g_queue[1]+g_queue[2]+g_queue[3]+g_queue[4])/_REPEAT_IR_CNT == ucKeyState)
		{
			g_IRKeyRepeatTimes = _REPEAT_IR_CNT;
			g_IRKeyValue = ucKeyState;
		}
		else
		{
			g_IRKeyRepeatTimes = 0;
			g_IRKeyValue = _RELEASE_KEY_MASK;
		}
		
		ScalerTimerReactiveTimerEvent(SEC(0.2), _USER_TIMER_EVENT_IR_REPEAT_HOLD);
		//DebugMessageSystem("-LHH-repeat",g_IRKeyRepeatTimes);
	}

    return ucKeyState;
}
#endif // End of #if(_IR_SUPPORT == _IR_HW_SUPPORT)

#endif//#if(_OSD_TYPE == _KEC_OSD)
